package main

import (
	"bufio"
	_ "errors"
	"fmt"
	"os"

	"gitee.com/jnshao/go-start/basic/functional/fib"
)

func tryDefer() {
	for i := 0; i < 100; i++ {
		//defer先不执行该行代码，等调用函数快退出（执行结束前/异常程序中断前）在执行
		//defer执行代码段保存在栈中，执行顺序先进后出
		//遇到return/error 也会把先前存入的代码段运行
		defer fmt.Println(i) //参数在defer语句时计算，值传递，写入defer列表参数已经保存计算好了,不会出现i为30个30
		if i == 30 {
			// Uncomment panic to see
			// how it works with defer
			//panic("printed too many")
		}
	}
}

func writeFile(filename string) {
	// file, err := os.Create(filename)
	// if err != nil {
	// 	panic(err)
	// }

	//err是*os.PathError类型
	file, err := os.OpenFile(filename,
		os.O_EXCL|os.O_CREATE|os.O_WRONLY, 0666) //0666权限可读可写

	//自己建error
	//err = errors.New("this is a custom error") //errorString类型

	//错误处理
	if err != nil {
		if pathError, ok := err.(*os.PathError); !ok {
			panic(err)
		} else {
			fmt.Printf("%s, %s, %s\n",
				pathError.Op,
				pathError.Path,
				pathError.Err)
		}
		return
	}
	defer file.Close() //就近写，不要考虑先进后出

	//使用bufio写文件，速度快,相当于stream读写器，先把数据存入缓存
	//避免直接使用file.Read()/file.Write()，频繁调用IO，影响性能
	writer := bufio.NewWriter(file)
	defer writer.Flush() //将缓存数据写入硬盘文件中

	f := fib.Fibonacci()
	for i := 0; i < 20; i++ {
		fmt.Fprintln(writer, f()) //将f()写入writer缓存中
	}
}

func main() {
	tryDefer()
	writeFile("fib.txt")
}
